/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.jm.mala.view;

import br.jm.mala.entity.Modulos;
import br.jm.mala.entity.Roles;
import br.jm.mala.entity.RolesModulos;
import br.jm.mala.entity.RolesModulosPK;
import br.jm.mala.entity.User;
import br.jm.mala.lazyModel.GenericDataModel;
import br.jm.mala.lazyModel.GenericLazyDataModel;
import br.jm.mala.service.ModulosService;
import br.jm.mala.service.RolesModulosService;
import br.jm.mala.service.RolesService;
import br.jm.mala.service.UsuarioService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.comparators.ComparatorChain;
import org.primefaces.context.RequestContext;
import org.primefaces.model.LazyDataModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 *
 * @author joao
 */
@Component("usuarioView")
@Scope("view")
public class UsuarioView implements Serializable {

    private static final long serialVersionUID = 233067529147824573L;

    private LazyDataModel<User> userLazy;
    private LazyDataModel<Roles> rolesLazy;
    private User selectedUser;
    private Roles selectedRoles;
    private FacesMessage msg;
    private final UsuarioService userService;
    private final RolesService rolesService;
    private final RolesModulosService rolesModulosService;
    private final ModulosService modulosService;
    private final List<Modulos> listModulos;
    private GenericDataModel modulosDataModel;
    private Modulos[] selectedModulosRoles;
    private Roles[] selectedUserRoles;
    private String password2;

    @Autowired
    public UsuarioView(UsuarioService userService, RolesService rolesService, ModulosService modulosService, RolesModulosService rolesModulosService) {
        this.userService = userService;
        this.rolesService = rolesService;
        this.modulosService = modulosService;
        this.rolesModulosService = rolesModulosService;

        this.selectedRoles = new Roles();
        this.selectedUser = new User();

        this.listModulos = modulosService.loadAll();
        List sortFields = new ArrayList();
        sortFields.add(new BeanComparator("numNivel"));
        sortFields.add(new BeanComparator("ordem"));
        ComparatorChain multiSort = new ComparatorChain(sortFields);
        java.util.Collections.sort(this.listModulos, multiSort);

        this.modulosDataModel = new GenericDataModel(this.listModulos);
        this.userLazy = new GenericLazyDataModel(userService, null, null, "User");
        this.rolesLazy = new GenericLazyDataModel(rolesService, null, null, "Roles");

        MenuView.salvar = true;
    }

    public LazyDataModel<User> getUserLazy() {
        return userLazy;
    }

    public void setUserLazy(LazyDataModel<User> userLazy) {
        this.userLazy = userLazy;
    }

    public User getSelectedUser() {
        return selectedUser;
    }

    public void setSelectedUser(User selectedUser) {
        this.selectedUserRoles = new Roles[selectedUser.getRoles().size()];
        if (selectedUser.getRoles().size() > 0) {
            for (int i = 0; i < selectedUser.getRoles().size(); i++) {
                this.selectedUserRoles[i] = selectedUser.getRoles().get(i);
            }
        }
        this.password2 = selectedUser.getPassword();
        this.selectedUser = selectedUser;
    }

    public void preparaInserir(ActionEvent event) {
        this.selectedUserRoles = new Roles[0];
        MenuView.salvar = true;
        this.selectedUser = new User();
        this.selectedUser.setTheme("blitzer");
    }

    public void inserir(ActionEvent actionEvent) {
        msg = null;

        try {
            if (ValidaUser()) {
                this.selectedUser.setUser_id(null);
                this.selectedUser.setRoles(Arrays.asList(this.selectedUserRoles));
                this.userService.create(selectedUser);

                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Usuário Inserido com Sucesso!", this.selectedUser.getNomUser());
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Inserir", this.selectedUser.getNomUser());
        } finally {
            this.preparaInserir(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void alterar(ActionEvent actionEvent) {
        msg = null;

        try {
            if (ValidaUser()) {
                this.selectedUser.setRoles(Arrays.asList(this.selectedUserRoles));
                this.userService.edit(selectedUser);
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Usuário Alterado com Sucesso!", this.selectedUser.getNomUser());
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Alterar", this.selectedUser.getNomUser());
        } finally {
            this.preparaInserir(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void excluir(ActionEvent actionEvent) {
        msg = null;

        try {
            this.userService.destroy(selectedUser);

            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Usuário Excluido com Sucesso", this.selectedUser.getNomUser());
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Excluir: " + this.selectedUser.getNomUser(), "USUÁRIO SENDO UTILIZADO EM ALGUM PROCESSO!");
        } finally {
            this.preparaInserir(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void preparaInserirRoles(ActionEvent event) {
        MenuView.salvar = true;
        this.selectedRoles = new Roles();
        this.selectedModulosRoles = new Modulos[0];
    }

    public void inserirRoles(ActionEvent actionEvent) {
        msg = null;

        try {
            List<Modulos> listRolesModulos = Arrays.asList(this.selectedModulosRoles);

            if (this.selectedModulosRoles.length == 0) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Obrigatório Selecionar pelo menos Hum Grupo!", this.selectedRoles.getNomFantasia());
            } else if (this.selectedRoles.getNomFantasia().isEmpty()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Obrigatório preencher o Campo Nome!", this.selectedRoles.getNomFantasia());
            } else {
                this.selectedRoles.setRole_id(null);
                this.selectedRoles.setDescription("ROLE_".concat(this.selectedRoles.getNomFantasia().trim()));
                this.selectedRoles.setRolesModulosList(listRolesModulos);
                this.rolesService.create(this.selectedRoles);

                for (Modulos selectedModulosRole : this.selectedModulosRoles) {
                    RolesModulos selectedRolesModulos = new RolesModulos();
                    RolesModulosPK rolesModulosPK = new RolesModulosPK();
                    rolesModulosPK.setModuloId(selectedModulosRole.getModuloId());
                    rolesModulosPK.setRoleId(selectedRoles.getRole_id());

                    selectedRolesModulos.setRolesModulosPK(rolesModulosPK);
                    selectedRolesModulos.setAlterar(selectedModulosRole.getAlterar());
                    selectedRolesModulos.setConsultar(selectedModulosRole.getConsultar());
                    selectedRolesModulos.setExcluir(selectedModulosRole.getExcluir());
                    selectedRolesModulos.setIncluir(selectedModulosRole.getIncluir());
                    selectedRolesModulos.setModulos(selectedModulosRole);
                    selectedRolesModulos.setRoles(selectedRoles);
                    this.rolesModulosService.edit(selectedRolesModulos);
                }

                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Grupo Inserido com Sucesso!", this.selectedRoles.getNomFantasia());
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Inserir", this.selectedRoles.getNomFantasia());
        } finally {
            this.preparaInserirRoles(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void alterarRoles(ActionEvent actionEvent) {
        msg = null;

        try {
            List<Modulos> listRolesModulos = Arrays.asList(this.selectedModulosRoles);

            if (this.selectedRoles.getRole_id() == 1) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Grupo Administrador não pode ser Alterado!", this.selectedRoles.getNomFantasia());
            } else if (this.selectedModulosRoles.length == 0) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Obrigatório Selecionar pelo menos Hum Grupo!", this.selectedRoles.getNomFantasia());
            } else if (this.selectedRoles.getNomFantasia().isEmpty()) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Obrigatório preencher o Campo Nome!", this.selectedRoles.getNomFantasia());
            } else {
                this.selectedRoles.setDescription("ROLE_".concat(this.selectedRoles.getNomFantasia().trim()));
                this.selectedRoles.setRolesModulosList(listRolesModulos);
                this.rolesService.edit(this.selectedRoles);

                for (Modulos selectedModulosRole : this.selectedModulosRoles) {
                    RolesModulos selectedRolesModulos = new RolesModulos();
                    RolesModulosPK rolesModulosPK = new RolesModulosPK();
                    rolesModulosPK.setModuloId(selectedModulosRole.getModuloId());
                    rolesModulosPK.setRoleId(selectedRoles.getRole_id());

                    selectedRolesModulos.setRolesModulosPK(rolesModulosPK);
                    selectedRolesModulos.setAlterar(selectedModulosRole.getAlterar());
                    selectedRolesModulos.setConsultar(selectedModulosRole.getConsultar());
                    selectedRolesModulos.setExcluir(selectedModulosRole.getExcluir());
                    selectedRolesModulos.setIncluir(selectedModulosRole.getIncluir());
                    selectedRolesModulos.setModulos(selectedModulosRole);
                    selectedRolesModulos.setRoles(selectedRoles);
                    this.rolesModulosService.edit(selectedRolesModulos);
                }

                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Grupo Alterado com Sucesso!", this.selectedRoles.getNomFantasia());
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Alterar", this.selectedRoles.getNomFantasia());
        } finally {
            this.preparaInserirRoles(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void excluirRoles(ActionEvent actionEvent) {
        msg = null;

        try {
            if (this.selectedRoles.getRole_id() == 1) {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Grupo Administrador não pode ser Excluido!", this.selectedRoles.getNomFantasia());
            } else {
                this.rolesService.destroy(selectedRoles);
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Grupo Excluido com Sucesso!", this.selectedRoles.getNomFantasia());
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Excluir: " + this.selectedRoles.getNomFantasia(), "GRUPO SENDO UTILIZADO EM ALGUM PROCESSO!");
        } finally {
            this.preparaInserirRoles(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public LazyDataModel<Roles> getRolesLazy() {
        return rolesLazy;
    }

    public void setRolesLazy(LazyDataModel<Roles> rolesLazy) {
        this.rolesLazy = rolesLazy;
    }

    public Roles getSelectedRoles() {
        return selectedRoles;
    }

    public void setSelectedRoles(Roles selectedRoles) {
        String cSql;
        this.modulosDataModel = new GenericDataModel(this.listModulos);
        this.selectedModulosRoles = new Modulos[this.listModulos.size()];
        if (selectedRoles.getRolesModulosList().size() > 0) {
            for (int i = 0; i < selectedRoles.getRolesModulosList().size(); i++) {
                cSql = "select role_id,modulo_id,incluir,alterar,consultar,excluir from roles_modulos where role_id = "
                        + selectedRoles.getRole_id() + " and modulo_id = " + selectedRoles.getRolesModulosList().get(i).getModuloId();
                RolesModulos seletecdRolesModulosTemp = rolesModulosService.getNativeFiltro(cSql);
                selectedRoles.getRolesModulosList().get(i).setIncluir(seletecdRolesModulosTemp.getIncluir());
                selectedRoles.getRolesModulosList().get(i).setAlterar(seletecdRolesModulosTemp.getAlterar());
                selectedRoles.getRolesModulosList().get(i).setExcluir(seletecdRolesModulosTemp.getExcluir());
                selectedRoles.getRolesModulosList().get(i).setConsultar(seletecdRolesModulosTemp.getConsultar());
                this.selectedModulosRoles[i] = selectedRoles.getRolesModulosList().get(i);
            }
        }

        this.selectedRoles = selectedRoles;
    }

    public Modulos[] getSelectedModulosRoles() {
        return selectedModulosRoles;
    }

    public void setSelectedModulosRoles(Modulos[] selectedModulosRoles) {
        this.selectedModulosRoles = selectedModulosRoles;
    }

    public GenericDataModel getModulosDataModel() {
        return modulosDataModel;
    }

    public void setModulosDataModel(GenericDataModel modulosDataModel) {
        this.modulosDataModel = modulosDataModel;
    }

    public Roles[] getSelectedUserRoles() {
        return selectedUserRoles;
    }

    public void setSelectedUserRoles(Roles[] selectedUserRoles) {
        this.selectedUserRoles = selectedUserRoles;
    }

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }

    public boolean ValidaUser() {
        RequestContext context = RequestContext.getCurrentInstance();

        boolean lReturn = true;

        if (this.selectedUser.getPassword().isEmpty()) {
            lReturn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ... Password em Branco!", this.selectedUser.getNomUser());
        } else {
            if (!this.selectedUser.getPassword().equals(this.password2)) {
                lReturn = false;
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ... Confirmação de Password Incorreto!", this.selectedUser.getNomUser());
            }
        }
        if (this.selectedUser.getNomUser().isEmpty()) {
            lReturn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ... Nome do Usuário em Branco!", this.selectedUser.getNomUser());
        } else if (this.selectedUser.getUsername().isEmpty()) {
            lReturn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ... Username em Branco!", this.selectedUser.getNomUser());
        } else if (this.selectedUser.getTheme() == null) {
            this.selectedUser.setTheme("blitzer");
        } else if (this.selectedUserRoles.length == 0) {
            lReturn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ... Obrigatório Selecionar um GRUPO!", this.selectedUser.getNomUser());
        }

        context.addCallbackParam("loggedIn", lReturn);
        if (lReturn) {
            context.update("frmPrincipal:panel");
            context.scrollTo("frmPrincipal:panel");
        }
        context.update("frmPrincipal:messages");
        context.scrollTo("frmPrincipal:messages");

        return lReturn;
    }
}
